﻿#include "GnsOften.h"

#if WIN32
	#include <assert.h>
#endif

#include "SystemMgr.h"

CCGnsOften::CCGnsOften()
{
}


CCGnsOften::~CCGnsOften()
{
}

// 判断两个浮点数是否相等
bool CCGnsOften::floatEqual(float f1, float f2, float errorRange)
{
	if (fabs(f1 - f2) < errorRange)
		return true;

	return false;
}

float CCGnsOften::maxFloat(float x, float y)
{
	return (x > y ? x : y);
}

float CCGnsOften::minFloat(float x, float y)
{
	return (x < y ? x : y);
}

// 安全的字符串拷贝
int CCGnsOften::snprintf_safe(char* szDst, int iDstSize, const char* szSrc, int iSrcLen)
{
	#if WIN32
		if (iDstSize < iSrcLen + 1)
			assert(false);
	#endif
	
	if (iDstSize <= iSrcLen + 1)
	{
		memcpy(szDst, szSrc, iDstSize);
		szDst[iDstSize - 1] = 0;   // 最后一个清成 0
		return iDstSize;
	}
	else
	{
		memcpy(szDst, szSrc, iSrcLen+1);
		szDst[iSrcLen + 1] = 0;   // 最后一个清成 0
		return iSrcLen + 1;
	}
}

// 安全的字符串拷贝
int CCGnsOften::memcpy_safe(char* szDst, int iDstSize, const char* szSrc, int iSrcSize)
{
	#if WIN32
		if (iDstSize < iSrcSize)
			assert(false);
	#endif

	int iMin = 0;

	// 选出最小值
	if (iDstSize < iSrcSize)   
		iMin = iDstSize;
	else
		iMin = iSrcSize;

	memcpy(szDst, szSrc, iMin);

	return iMin;
}

// 获得“在代码里直接赋值”的字串内容的 UTF8 值
std::string  CCGnsOften::getUtf8_DirectAssignmentInProgram(const std::string&  strIn)
{
	std::string  strUtf8;

	if (strIn.length() <= 0)   // 长度为0，不用转换
	{
		assert(false);
		return strUtf8;
	}

	#if CC_TARGET_PLATFORM==CC_PLATFORM_WIN32 
		// Windows 下天然就是 GB2312 格式，所以需要转码
		strUtf8 = SystemMgr::getInstance()->GbToUTF8(strIn.c_str());
		return strUtf8;
	#else
		// Android 下天然就是 UTF8 格式，不用转码
		return strIn;
	#endif
}

// 获得“在代码里直接赋值”的字串内容的 GB2312 值
std::string  CCGnsOften::getGB2312_DirectAssignmentInProgram(const std::string&  strIn)
{
	std::string  strGB;

	if (strIn.length() <= 0)   // 长度为0，不用转换
	{
		assert(false);
		return strGB;
	}

	#if CC_TARGET_PLATFORM==CC_PLATFORM_WIN32 
		// Windows 下天然就是 GB2312 格式，不用转码
		return strIn;   
	#else 
		// Android 下天然就是 UTF8 格式，需要转码
		strGB = SystemMgr::getInstance()->utf8ToGb(strIn.c_str());
		return strGB;
	#endif
}

bool CCGnsOften::isNumber(string &s)
{
	if (s.length() == 0 || s.find("-")!=string::npos)
		return false;

	stringstream sin(s);
	int t;
	char p;
	if (!(sin >> t))
		return false;
	if (sin >> p)
		return false;
	else
		return true;
}

bool CCGnsOften::isNoChinese(string &strIn)
{
	int iStrLen = strIn.length();
	unsigned char tmp_1 = 0;

	if (0 == iStrLen)
	{
		return false;  // 无效编码
	}

	for (int i = 0; i < (int)strIn.length(); ++i)
	{
		tmp_1 = strIn[i];
		if (tmp_1 < 32 || tmp_1 > 127)   // 标准的字符
			return false;
	}

	return true;	
}

bool CCGnsOften::checkStrLength(string &s,int minLen,int maxLen)
{
	int len = (int)s.length();
	return len >= minLen && len <= maxLen;
}

bool CCGnsOften::isNoSpace(string &s)
{
	return s.find(" ") == string::npos;
}

//检查管理账号 全数字 6-14
bool  CCGnsOften::checkMgrID(string &s)
{
	return checkStrLength(s, 6, 14) && isNumber(s);
}
//检查玩家账号 英文数字 6-14
bool CCGnsOften::checkPlayerID(string &s)
{
	return checkStrLength(s, 6, 14) && isNoSpace(s) && isNoChinese(s);
}
//检查玩家昵称 6-14
bool CCGnsOften::checkPlayerName(string &s)
{
	return checkStrLength(s, 6, 14) && isNoSpace(s);
}
//检查备注名 6-14
bool CCGnsOften::checkRemarkName(string &s)
{
	return checkStrLength(s, 6, 14) && isNoSpace(s);
}
//检查手机号 全数字20
bool CCGnsOften::checkPhoneNum(string &s)
{
	return checkStrLength(s, 1, 14) && isNumber(s);
}
//检查密码 英文数字6-14
bool CCGnsOften::checkPassWord(string &s)
{
	return checkStrLength(s, 6, 14)  && isNoSpace(s) && isNoChinese(s);
}
//检查备注 90
bool CCGnsOften::checkBeiZhu(string &s)
{
	return checkStrLength(s, 0, 90);
}
/* --------------------------------------------------------------------------
函数说明：判断字符串是否 GB2312 的编码，
					注意：此函数通过了 test_gb2312_forward_direction 和 test_gb2312_negative_direction 验证
								此函数的测试程度有限，若要做到精准判断，还需要更深入和更大量的测试。
								目前仅仅作为参考性的判断。
传入参数：
	strIn		要判断的字符串
返回值：
	true   strIn 为 GB2312 的编码
	false  strIn 为 非GB2312（可能是UTF8） 的编码
-------------------------------------------------------------------------- */
bool CCGnsOften::IsGB2312(const string& strIn)
{
	int iStrLen = strIn.length();
	int iStrSize = strIn.size();

	unsigned char tmp_1 = 0;
	unsigned char tmp_2 = 0;
	unsigned char tmp_3 = 0;

	if (0 == iStrLen)
	{
		return false;  // 无效编码
	}
	else if (1 == iStrLen)   // 说明是单个字符，对单个字节进行判断
	{
		tmp_1 = strIn[0];
		if (tmp_1 >= 33 && tmp_1 <= 126)   // 标准的字符
			return true;

		return false;  // 非标准字符
	}

	for (int i = 0; i < (int)strIn.length(); ++i)
	{
		tmp_1 = strIn[i];
		if (tmp_1 > 127 && tmp_1 >= 228 && tmp_1 <= 233)  // 进入 UTF8 的编码判断
		{
			int iTmpLen = strlen(strIn.c_str());  // 测试用

			//if ((i + 2) >= strlen(strIn.c_str()) - 1)   // 这个判断有错，如果只是一个UTF8的“黄”字，那就返回 GB的判断啦，明显是错啦
			if ((i + 2) >= iStrLen)
				return true;		// 返回为 GB2312 的编码

			tmp_2 = strIn[i + 1];
			tmp_3 = strIn[i + 2];
			if (tmp_2 >= 128 && tmp_2 <= 191 && tmp_3 >= 128 && tmp_3 <= 191)
				return false;       // 返回非GB2312（可能是UTF8） 的编码
			else
				return true;		// 返回为GB2312的编码
		}
	}

	return true;
}
